<?php
/**
 * 文件路径： \application\index\job\Hello.php
 * 这是一个消费者类，用于处理 helloJobQueue 队列中的任务
 */
namespace app\index\job;

use app\admin\library\RedisHash;
use think\Cache;
use think\Env;
use think\queue\Job;

/**
 *
 * Class Equip
 * @package app\index\job
 */
class Pet
{

    protected $redisHash = null;

    public function __construct()
    {
        $options = [
            'host'      => Env::get('redis.host'),
            'port'      => 6379,
            'password'  => Env::get('redis.pass'),
            'select'    => 0,
            'timeout'   => 0,
            'persistent'=> false,
        ];
        $this->redisHash = new RedisHash($options);
    }

    /**
     * fire方法是消息队列默认调用的方法
     * @param Job $job 当前的任务对象
     * @param array|mixed $data 发布任务时自定义的数据
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function fire(Job $job,$data)
    {
        $startTime = time();
        // 有些消息在到达消费者时,可能已经不再需要执行了
        $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
        if(!$isJobStillNeedToBeDone){
            $job->delete();
            return;
        }

        $isJobDone = $this->doHelloJob($data);
        if ($isJobDone) {
              // 如果任务执行成功， 记得删除任务
              $job->delete();
              $useTime = time() - $startTime;
              print("<info>Data sync is success, spent  $useTime  s "."</info>\n");
          }else{
              if ($job->attempts() > 3) {
                  //通过这个方法可以检查这个任务已经重试了几次了
                  print("<warn>Hello Job has been retried more than 3 times!"."</warn>\n");

                  $job->delete();

                  // 也可以重新发布这个任务
                  //print("<info>Hello Job will be availabe again after 2s."."</info>\n");
                  //$job->release(2); //$delay为延迟时间，表示该任务延迟2秒后再执行
              }
          }
    }

    /**
     * 有些消息在到达消费者时,可能已经不再需要执行了
     * @param array|mixed $data 发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data)
    {
        foreach ($data as $item) {
            $ret = \app\admin\model\file\Pet::get($item);
            if (empty($ret)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据消息中的数据进行实际的业务处理...
     */
    private function doHelloJob($data)
    {
        foreach ($data as $item) {
            $ret = \app\admin\model\file\Pet::get($item);
            $info = $this->redisHash->hget('pet',$item);
            if (empty($ret)) {
                \app\admin\model\file\Pet::create(json_decode($info,true));
            } else {
                \app\admin\model\file\Pet::update(json_decode($info,true));
            }
        }
        return true;
    }
}
